package sfsoftware.util;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.xml.sax.SAXException;

import sfsoftware.game.TrevorLegacy;
import sfsoftware.game.actor.ScriptedActor;
import sfsoftware.game.actor.item.Item;
import sfsoftware.game.trevor.Player;
import sfsoftware.game.trevor.ui.Dialog;
import sfsoftware.util.map.MapReader;

public class Script implements Iterator<String>, Updatable {
	private static HashMap<String, String> variables = new HashMap<String, String>();	
	private static String[] reservedVariableNames = new String[] {"gameCounter","x", "X", "now", "this", "result", "actor"};	
	private static Vector<Script> runningScripts = new Vector<Script>();
	private static boolean verbose = true;	
	
	private LinkedList<String> lines = new LinkedList<String>();
	private String fileName;
	private HashMap<String, String> localVariables = new HashMap<String, String>();
	
	private ScriptedActor actor = null;
	private Clock clock = null;
	private int waitTimer = 0;

	/**
	 * Constructs a new instance of the Script class with an associated Actor attached.
	 *  
	 * @param filename
	 * @param associatedActor
	 * @param argList
	 */
	public Script(String filename, ScriptedActor associatedActor, String[] argList)
	{
		for(int i=0; i < argList.length; i++)
		{
			if(argList[i].indexOf("=") != -1)
			{
				String[] s = argList[i].split("=");
				localVariables.put(s[0],s[1]);
			}
		}
		
		actor = associatedActor;
		clock = new Clock(1);
		fileName = getFileContents(filename);		
	}	
	
	/**
	 * Constructs a new instance of the Script class with an associated Actor attached.
	 *  
	 * @param filename
	 * @param associatedActor
	 */
	public Script(String filename, ScriptedActor associatedActor)
	{
		actor = associatedActor;
		clock = new Clock(1);
		fileName = getFileContents(filename);		
	}
	
	/**
	 * Constructs a new instance of the Script class and includes a list of arguments.
	 * 
	 * @param filename
	 * @param argList
	 */
	public Script(String filename, String[] argList)
	{		
		for(int i=0; i < argList.length; i++)
		{
			if(argList[i].indexOf("=") != -1)
			{
				String[] s = argList[i].split("=");
				localVariables.put(s[0],s[1]);
			}
		}
		clock = new Clock(1);
		fileName = getFileContents(filename);		
	}
	
	/**
	 * Constructs a new instance of the Script class.
	 * 
	 * @param filename
	 */
	public Script(String filename) 
	{
		clock = new Clock(1);
		fileName = getFileContents(filename);
	}

	public static boolean evaluate(String expression)
	{
		boolean result = false;
		String[] tokens = expression.split("[=<>!]+");
		
		String variable = tokens[0].trim();
		String value = tokens[1].trim();

		if(!(isNumeric(variable)))
		{
			variable = getGlobalVariable(variable);
		}
		
		if(!(isNumeric(value)))			
		{
			// The user provided a non-numeric value for this conditional - try loading a variable.
			value = getGlobalVariable(value);
		}		
		
		if(expression.matches(".*<=.*"))
		{				
			if(Double.valueOf(variable) <= Double.valueOf(value))
			{
				result = true;
			}
		}		
		else if(expression.matches(".*>=.*"))
		{
			if(Double.valueOf(variable) >= Double.valueOf(value))
			{
				result = true;
			}
		}
		else if(expression.matches(".*!=.*"))
		{
			if(!(variable.equals(value)))
			{					
				result = true;
			}
		}
		else if(expression.matches(".*=.*"))
		{				
			if(variable.equals(value))
			{					
				result = true;
			}
		}
		else if(expression.matches(".*<.*"))
		{
			if(Double.valueOf(variable) < Double.valueOf(value))
			{
				result = true;
			}
		}		
		else if(expression.matches(".*>.*"))
		{
			if(Double.valueOf(variable) > Double.valueOf(value))
			{
				result = true;
			}
		}			
		
		return result;
	}
	
	private String getFileContents(String filename)
	{
		try
		{
			  FileInputStream in = new FileInputStream(filename);
			  BufferedReader br = new BufferedReader(new InputStreamReader(in));
			  String strLine;
		 
			  while((strLine = br.readLine())!= null)
			  {
				  if(strLine.trim().length() > 0)
				  {
					  lines.add(strLine.trim());
				  }
			  }				
			  runningScripts.add(this);
			  br.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}	
		
		return filename;
	}
	
	private static String getGlobalVariable(String variableName)
	{
		String value = ""; 
		if(variableName.equals("gameCounter"))
		{
			value = Clock.getFormattedHoursMinutes(TrevorLegacy.gameCounter);
		}
		else if(variableName.equals("result"))
		{			
			value = String.valueOf(Dialog.result);
		}
		else if(variableName.equals("this"))
		{
			value = null;
		}
		else if(variableName.equals("now"))
		{
			value = (new Date()).toString();
		}
		else if(variableName.equalsIgnoreCase("x"))
		{
			value = variables.get("Temp");
		}
		else if(variableName.equals("actor"))
		{			
			value = null;
			//TODO Retrieve attributes from Actor
		}
		else if(variableName.length() >= 6 && variableName.substring(0, 6).equalsIgnoreCase("items."))
		{
			String itemName = variableName.substring(variableName.lastIndexOf(".") + 1, variableName.length());
			value = "0";
			
			if(itemName.equalsIgnoreCase("ruples"))
			{
				value = String.valueOf(Player.getRuples());				
			}
			else if(Player.getInventory().contains(itemName.replaceAll("_", " ")))
			{
				value = "1";
			}
		}
		else if(variableName.length() >= 6 && variableName.substring(0, 6).equalsIgnoreCase("actor."))
		{
			value = null;
		}
		else if(variableName.length() >= 7 && variableName.substring(0, 7).equalsIgnoreCase("player."))
		{
			String actorAttribute = variableName.substring(variableName.lastIndexOf(".") + 1, variableName.length());
			if(actorAttribute.equalsIgnoreCase("health"))
			{
				value = String.valueOf(Player.getHealth());
			}
			if(actorAttribute.equalsIgnoreCase("maxhealth"))
			{
				value = String.valueOf(Player.getMaxHealth());
			}
			if(actorAttribute.equalsIgnoreCase("damageresistance"))
			{
				value = String.valueOf(Player.getDamageResistance());
			}
			if(actorAttribute.equalsIgnoreCase("luck"))
			{
				value = String.valueOf(Player.getLuck());
			}
		}
		else
		{
			// First, check the global variable hashmap
			value = variables.get(variableName); 
			if(value == null)
			{
				// Variable must not exist in either scope - toss back 0
				value = "0";
			}
		}
		return value;		
	}
	
	private String getVariable(String variableName)
	{		
		String value = ""; 
		if(variableName.equals("gameCounter"))
		{
			value = Clock.getFormattedHoursMinutes(TrevorLegacy.gameCounter);
		}
		else if(variableName.equals("result"))
		{			
			value = String.valueOf(Dialog.result);
		}
		else if(variableName.equals("this"))
		{
			value = fileName;
		}
		else if(variableName.equals("now"))
		{
			value = (new Date()).toString();
		}
		else if(variableName.equalsIgnoreCase("x"))
		{
			value = variables.get("Temp");
		}
		else if(variableName.equals("actor") && actor != null)
		{			
			value = String.valueOf(actor.toString());
			//TODO Retrieve attributes from Actor
		}
		else if(variableName.length() >= 6 && variableName.substring(0, 6).equalsIgnoreCase("items."))
		{
			String itemName = variableName.substring(variableName.lastIndexOf(".") + 1, variableName.length());
			value = "0";			

			// Return a count of the player's money!			
			if(itemName.equalsIgnoreCase("ruples"))
			{
				value = String.valueOf(Player.getRuples());				
			}
			// If an item is unique and the player has it, return 1
			else if(Item.isUnique(itemName.replaceAll("_", " ")) && Player.getInventory().contains(itemName.replaceAll("_", " ")))
			{
				value = "1";
			}
			// Non-unique item count.
			else if(Player.getInventory().contains(itemName.replaceAll("_", " ")))
			{
				value = String.valueOf(Player.getInventory().getItemCount(itemName.replaceAll("_", " ")));					
			}
		}
		else if(variableName.length() >= 6 && actor != null && variableName.substring(0, 6).equalsIgnoreCase("actor."))
		{
			String actorAttribute = variableName.substring(variableName.lastIndexOf(".") + 1, variableName.length());
			if(actorAttribute.equalsIgnoreCase("speed"))
			{
				value = String.valueOf(actor.getSpeed());
			}
			else if(actorAttribute.equalsIgnoreCase("walkable"))
			{
				value = String.valueOf(actor.getWalkable());
			}	
			else if(actorAttribute.equalsIgnoreCase("x"))
			{
				value = String.valueOf(actor.getX());
			}
			else if(actorAttribute.equalsIgnoreCase("y"))
			{				
				value = String.valueOf(actor.getY());
			}				
		}
		else if(variableName.length() >= 7 && variableName.substring(0, 7).equalsIgnoreCase("player."))
		{
			String actorAttribute = variableName.substring(variableName.lastIndexOf(".") + 1, variableName.length());
			if(actorAttribute.equalsIgnoreCase("health"))
			{
				value = String.valueOf(Player.getHealth());
			}
			if(actorAttribute.equalsIgnoreCase("maxhealth"))
			{
				value = String.valueOf(Player.getMaxHealth());
			}
			if(actorAttribute.equalsIgnoreCase("damageresistance"))
			{
				value = String.valueOf(Player.getDamageResistance());
			}
			if(actorAttribute.equalsIgnoreCase("luck"))
			{
				value = String.valueOf(Player.getLuck());
			}
		}
		else
		{
			// First, check the global variable hashmap
			value = variables.get(variableName); 
			if(value == null)
			{
				// If we couldn't find the specified variable there, try the local variables
				value = localVariables.get(variableName);
				if(value == null)
				{
					// Variable must not exist in either scope - toss back 0
					value = "0";
				}
			}
		}
		return value;
	}
	
	@Override
	public boolean hasNext() {		
		if(lines.size() > 0)
		{
			return true;
		}		
		else
		{
			return false;
		}
	}
	
	private static boolean isNumeric(String s) {  
	    return s.matches("[-+]?\\d*\\.?\\d+");  
	}
	
	/**
	 * Returns a boolean indicating whether or not a specified script file is currently running.
	 * 
	 * @param filename	The filename of the script in question.
	 * @return boolean
	 */
	public static boolean isScriptRunning(String filename)
	{
		for(Iterator<Script> i = runningScripts.iterator(); i.hasNext();)
		{
			Script temp = i.next();
			if(temp.toString().equalsIgnoreCase(filename))
			{				
				return true;
			}
		}
		
		return false;
	}
	
	@Override
	public String next() {		
		String nextLine = lines.getFirst();
		lines.removeFirst();
		
		return nextLine;
	}

	@Override
	public void remove() {
		throw new UnsupportedOperationException("This operation is unsupported for Scripts");	
	}

	private boolean parse(String line)
	{				
		String[] tokens = line.split("[ ]");		
		// COMMENT				
		if(line.substring(0, 1).equalsIgnoreCase("'") && verbose)
		{
			String output = line.substring(1);
			
			Pattern pattern = Pattern.compile("%(.*?)%");
		    Matcher m = pattern.matcher(output);
		    StringBuffer sb = new StringBuffer();
		    while (m.find())
		    {		    	
		    	m.appendReplacement(sb, getVariable(m.group(1)));
		    }
		    
		    m.appendTail(sb);
			
			System.out.println("*** " + sb);
		}
		// INCREMENT
		else if(line.length() >= 2 && line.substring(line.length() - 2, line.length()).equalsIgnoreCase("++"))
		{
			String variableName = line.substring(0, line.length() - 2).trim();
			String value = getVariable(variableName);
			
			value = Integer.toString((Integer.valueOf(value) + 1));			
			setVariable(variableName, value);
		}
		// DECREMENT
		else if(line.length() >= 2 && line.substring(line.length() - 2, line.length()).equalsIgnoreCase("--"))
		{
			String variableName = line.substring(0, line.length() - 2).trim();
			String value = getVariable(variableName);
			
			value = Integer.toString((Integer.valueOf(value) - 1));			
			setVariable(variableName, value);
		}
		// IF
		else if(line.length() >= 2 && line.substring(0, 2).equalsIgnoreCase("if"))
		{
			String expression = line.substring(3, line.length() - 1).trim();
			tokens = expression.split("[=<>!]+");
			
			String variable = tokens[0].trim();
			String value = tokens[1].trim();
			
			if(!(isNumeric(variable)))
			{
				variable = getVariable(variable);
			}
			
			if(!(isNumeric(value)))			
			{
				// The user provided a non-numeric value for this conditional - try loading a variable.
				value = getVariable(value);
			}
			
			if(expression.matches(".*<=.*"))
			{				
				if(Double.valueOf(variable) > Double.valueOf(value))
				{
					skipLines();
				}
			}		
			else if(expression.matches(".*>=.*"))
			{
				if(Double.valueOf(variable) < Double.valueOf(value))
				{
					skipLines();
				}
			}
			else if(expression.matches(".*!=.*"))
			{
				if(variable.equals(value))
				{					
					skipLines();
				}
			}
			else if(expression.matches(".*=.*"))
			{				
				if(!(variable.equals(value)))
				{					
					skipLines();
				}
			}
			else if(expression.matches(".*<.*"))
			{
				if(Double.valueOf(variable) >= Double.valueOf(value))
				{
					skipLines();
				}
			}		
			else if(expression.matches(".*>.*"))
			{
				if(Double.valueOf(variable) <= Double.valueOf(value))
				{
					skipLines();
				}
			}	
		}		
		// SAY
		else if(line.length() >= 3 && line.substring(0, 3).equalsIgnoreCase("say"))
		{
			String output = line.substring(4).trim();
			Pattern pattern = Pattern.compile("%(.*?)%");
		    Matcher m = pattern.matcher(output);
		    StringBuffer sb = new StringBuffer();
		    while (m.find())
		    {
		    	m.appendReplacement(sb, getVariable(m.group(1)));
		    }
		    
		    m.appendTail(sb);			
			
		    if(sb.indexOf("|") != -1)
		    {
			    // Choices are delimited by | in the script file.
			    Vector<String> v = new Vector<String>();
			    v.addAll(Arrays.asList(sb.toString().split("\\s*\\|\\s*")));			   
			    
			    if(v.size() > 0)
			    {
			    	v.remove(0);			    	
			    	Dialog.setChoices(v);
			    }
			    sb = new StringBuffer(sb.substring(0, sb.indexOf("|")));
		    }
		    Dialog.raiseDialog(getVariable("Speaker") + ": " + sb);					
		}
		// SET
		else if(line.length() >= 3 && line.substring(0, 3).equalsIgnoreCase("set"))
		{
			String variableName = tokens[1];			
			String variableValue = getVariable("temp");
			// If they provided a new value for us...
			if(tokens.length > 2)
			{				
				variableValue = tokens[2];				
			}
			setVariable(variableName, variableValue);
		}
		// RUN
		else if(line.length() >= 4 && line.substring(0, 4).equalsIgnoreCase("run "))
		{
			if(tokens.length > 1)
			{	
				String scriptFile = tokens[1].trim();
				// If a path way not provided, assume the script they are trying to run is in the same directory
				if(scriptFile.indexOf("/") == -1)
				{
					scriptFile = fileName.substring(0, fileName.lastIndexOf("/") + 1) + scriptFile;
				}
				// Run the requested script.
				new Script(scriptFile);
			}			
		}
		// LOAD
		else if(line.length() >= 4 && line.substring(0, 4).equalsIgnoreCase("load"))
		{
			if(tokens.length > 1)
			{				
				setVariable("temp", getVariable(tokens[1].trim()));
			}
			else
			{
				setVariable("temp", "0");
			}
		}
		// WAIT
		else if(line.length() >= 5 && line.substring(0, 5).equalsIgnoreCase("wait "))
		{
			if(tokens.length > 1)
			{			
				waitTimer = Integer.valueOf(tokens[1].trim());
				clock = new Clock(waitTimer);
			}
		}		
		// BOSS
		else if(line.length() >= 5 && line.substring(0, 5).equalsIgnoreCase("boss "))
		{
			if(tokens.length > 1)
			{				
				System.out.println(getVariable(tokens[1].trim()));
				if(tokens[1].trim().equalsIgnoreCase("on"))
				{
					TrevorLegacy.bossFight = true;
				}
				else if(tokens[1].trim().equalsIgnoreCase("off"))
				{
					TrevorLegacy.bossFight = false;
				}
			}
			else
			{
				TrevorLegacy.bossFight = !(TrevorLegacy.bossFight);
			}
		}
		// PRINT
		else if(line.length() >= 5 && line.substring(0, 5).equalsIgnoreCase("print"))
		{
			if(tokens.length > 1)
			{				
				System.out.println(getVariable(tokens[1].trim()));
			}
			else
			{
				System.out.println(getVariable("temp"));
			}
		}				
		// LOADMAP
		// Usage:	loadmap file, mapX, mapY, playerX, playerY
		else if(line.length() >= 8 && line.substring(0, 8).equalsIgnoreCase("loadmap "))
		{
			String expression = line.substring(8, line.length() - 1).trim();			
			tokens = expression.split(",");
			if(tokens.length == 5)
			{
				String filename = tokens[0].trim();
				int mapX = Integer.valueOf(tokens[1].trim());
				int mapY = Integer.valueOf(tokens[2].trim());
				int playerX = Integer.valueOf(tokens[3].trim());
				int playerY = Integer.valueOf(tokens[4].trim());			
				
				try 
				{
					Player.getPlayer().move(playerX, playerY);
					MapReader.setMapFile(filename);			
					TrevorLegacy.initMap(mapX, mapY);
				} 
				catch (SAXException | IOException e) 
				{
					e.printStackTrace();
				}
			}
			else
			{
				System.out.println("*** Script Error: Insufficient parameters provided for command \"loadmap\"");
			}
		}
		// PLAYSOUND
		else if(line.length() >= 9 && line.substring(0, 9).equalsIgnoreCase("playsound"))
		{
			if(tokens.length > 1)
			{	
				tokens[1] = tokens[1].trim();				
				if(tokens[1].endsWith(".wav") || tokens[1].endsWith(".WAV"))
				{
					tokens[1] = tokens[1].substring(0, tokens[1].length() - 4);
				}
				
				Sound.playSound(tokens[1]);
			}
		}
		// END SCRIPT
		else if(line.length() >= 10 && line.substring(0, 10).equalsIgnoreCase("end script"))
		{
			lines.clear();			
		}		
		// ASSIGN (=)
		else if(line.indexOf("=") != -1)
		{
			tokens = line.split("=");			
			String variable = tokens[0].trim();
			String value = tokens[1].trim();
			
			if(value.split("\\s*[+\\-]\\s*").length == 1)
			{
				setVariable(variable, value);
			}
			else 
			{
				String delim = "((?<=[+\\-])|(?=[+\\-]))";
				double result = 0;
				boolean addition= true;
				//String expression = "";
				for(String token : value.split(delim))
				{
					token = token.trim();					
					if(isNumeric(token))
					{
						
						if(addition)
						{
							result = result + Double.valueOf(token);
						}
						else
						{
							result = result - Double.valueOf(token);
						}					
						//expression = expression + token;
					}
					else if(token.equals("+")) 
					{						
						addition = true;
						//expression = expression + "+";
					}
					else if(token.equals("-"))
					{						
						addition = false;
						//expression = expression + "-";
					}
					else 
					{						
						if(addition)
						{
							result = result + Double.valueOf(getVariable(token));
						}
						else
						{
							result = result - Double.valueOf(getVariable(token));
						}
						//expression = expression + getVariable(token);
					}					
				}										
				setVariable(variable, String.valueOf(result));
			}
		}
		else if(line.equalsIgnoreCase("actor.remove"))
		{
			if(actor != null)
			{
				actor.remove();
			}
			else
			{
				System.out.println("*** Script Error: No actor has been associated with the script currently executing!");
			}
		}
		// SPEAKER
		else if(line.length() >= 7 && line.substring(0, 7).equalsIgnoreCase("speaker"))
		{				
			setVariable("Speaker", line.substring(8, line.length()));			
		}
	
		return true;
	}
	
	private void setVariable(String variableName, String value)
	{			
		if(Arrays.asList(reservedVariableNames).contains(variableName))
		{
			System.out.println("*** Script Error: Cannot assign value to variable with reserved name!");
		}
		else if(variableName.length() >= 7 && variableName.substring(0, 7).equalsIgnoreCase("player."))
		{
			String actorAttribute = variableName.substring(variableName.lastIndexOf(".") + 1, variableName.length());
			if(actorAttribute.equalsIgnoreCase("health"))
			{
				if(isNumeric(value))
				{
					Player.setHealth(Integer.valueOf(value));
				}
				else
				{
					Player.setHealth(Integer.valueOf(getVariable(value)));
				}
			}
			if(actorAttribute.equalsIgnoreCase("maxhealth"))
			{		
				if(isNumeric(value))
				{
					Player.setMaxHealth(Integer.valueOf(value));
				}
				else
				{
					Player.setMaxHealth(Integer.valueOf(getVariable(value)));
				}
			}
			if(actorAttribute.equalsIgnoreCase("damageresistance"))
			{
				if(isNumeric(value))
				{
					Player.setDamageResistance(Integer.valueOf(value));
				}
				else
				{
					Player.setDamageResistance(Integer.valueOf(getVariable(value)));
				}
			}
			if(actorAttribute.equalsIgnoreCase("luck"))
			{				
				if(isNumeric(value))
				{
					Player.setLuck(Integer.valueOf(value));
				}
				else
				{
					Player.setLuck(Integer.valueOf(getVariable(value)));
				}
			}
		}
		else if(variableName.length() >= 6 && actor != null && variableName.substring(0, 6).equalsIgnoreCase("actor."))
		{	
			String actorAttribute = variableName.substring(variableName.lastIndexOf(".") + 1, variableName.length());
			if(actorAttribute.equalsIgnoreCase("speed"))
			{
				if(isNumeric(value))
				{
					actor.setSpeed(Integer.valueOf(value));
				}			
				else
				{
					actor.setSpeed(Integer.valueOf(getVariable(value)));
				}	
			}
			else if(actorAttribute.equalsIgnoreCase("walkable"))
			{
				actor.setWalkable(Boolean.valueOf(value));
			}
			else if(actorAttribute.equalsIgnoreCase("x"))
			{
				actor.setX(Integer.valueOf(value));
			}
			else if(actorAttribute.equalsIgnoreCase("y"))
			{
				actor.setY(Integer.valueOf(value));
			}			
			else if(actorAttribute.equalsIgnoreCase("destx"))
			{
				Double d = Double.valueOf(value);
				actor.setDestX(d.intValue());
			}			
			else if(actorAttribute.equalsIgnoreCase("desty"))
			{
				Double d = Double.valueOf(value);
				actor.setDestY(d.intValue());
			}	
			else if(actorAttribute.equalsIgnoreCase("dest"))
			{
				if(value.indexOf(",") != -1)
				{
					String[] s = value.split(",");
					actor.setDestX(Integer.valueOf(s[0].trim()));
					actor.setDestY(Integer.valueOf(s[1].trim()));
				}
			}
		}
		else if(variableName.length() >= 6 && variableName.substring(0, 6).equalsIgnoreCase("items."))
		{		
			//TODO Special code to handle adding items to inventory via script.
			String itemName = variableName.substring(variableName.lastIndexOf(".") + 1, variableName.length());
			if(itemName.equalsIgnoreCase("ruples"))
			{
				Player.setRuples(Double.valueOf(value).intValue());
			}
			else
			{
				if(Double.valueOf(value).intValue() > 0)
				{	
					int count = Double.valueOf(value).intValue();					
					// Add an item to inventory
					String texture = Item.properties.getProperty(itemName.toLowerCase() + ".texture", "items");
					String source = Item.properties.getProperty(itemName.toLowerCase() + ".source", "0,0");
					String size = Item.properties.getProperty(itemName.toLowerCase() + ".size", "40,40");
										
					int srcX = Integer.valueOf(source.substring(0, source.lastIndexOf(",")).trim());
					int srcY = Integer.valueOf(source.substring(source.lastIndexOf(",") + 1, source.length()).trim());
					
					int width = Integer.valueOf(size.substring(0, size.lastIndexOf(",")).trim());
					int height = Integer.valueOf(size.substring(size.lastIndexOf(",") + 1, size.length()).trim());
					
					Item temp = new Item(0, 0, texture, srcX, srcY, width, height, itemName.replaceAll("_", " "));
					temp.collisionResult(TrevorLegacy.player);
					// Remove the temporary object from the "cast" so it is never drawn.
					temp.remove();
				}
				else 
				{
					// Remove item from inventory
					Player.getInventory().remove(itemName.replaceAll("_", " "));
				}
			}			
		}
		else
		{		
			variables.put(variableName, value);
		}
	}
	
	private void skipLines()
	{		
		int conditionalCount =  1;
		if(hasNext())
		{			
			while(conditionalCount > 0)
			{	
				String currentLine = next();				
				if(currentLine.substring(0, 1).equalsIgnoreCase("}")) 
				{
					conditionalCount--;
				}
				else if(currentLine.length() >= 2 && currentLine.substring(0,2).equalsIgnoreCase("if"))
				{
					conditionalCount++;
				}											
			}
		}
	}
	
	@Override
	public String toString()
	{
		return fileName;
	}
	
	@Override
	public void update() {		
		if(clock.updateClock() && waitTimer > 0) {
			waitTimer = 0;			
		}
		
		if(waitTimer == 0)
		{
			if(hasNext())
			{
				String currentLine = next();
				parse(currentLine);			
			}
			else
			{
				runningScripts.remove(this);
			}
		}
	}
	
	/**
	 * Handles an update of all running scripts provided the game is not paused and a dialog is not raised.
	 */
	public static void updateRunningScripts()
	{
		if(!(sfsoftware.game.TrevorLegacy.isPaused) && !(Dialog.displayDialog))
		{
			Script[] s = new Script[runningScripts.size()];
			runningScripts.toArray(s);	
			
			for(int i = 0; i < s.length; i++)		
			{
				if(s[i].actor != null)
				{
					// If an Actor is attached to this script and hasn't move to his proper place, don't update!					
					if(s[i].actor.atDestLocation())
					{
						s[i].update();
					}
				}
				else
				{
					// If no Actor is attached, just update the script.
					s[i].update();
				}
			}
		}
	}
	
}
